home *** CD-ROM | disk | FTP | other *** search
/ The Best of Down Under Games / The Best of Down Under Games.iso / 3dfx Screen Savers / VoodooLights / Sources / mat.c < prev    next >
C/C++ Source or Header  |  1997-07-12  |  10KB  |  390 lines

  1. /*------------------------------------------------------/
  2. /                                                        /
  3. /    Copyright 1997, SΘrgio Durte <smd@di.fct.unl.pt>    /
  4. /                                                        /
  5. /------------------------------------------------------*/
  6.  
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include <stdlib.h>
  10.  
  11. #include "defines.h"
  12. #include "mat.h"
  13.  
  14. XYZ xyz_Zero = { 0.0, 0.0, 0.0 } ;
  15.  
  16. XYZW xyzw_Zero = { 0.0, 0.0, 0.0, 1.0 } ;
  17.  
  18. int mat_ipow( int b,  int e )
  19. {
  20.   int result = 1 ;
  21.   while( e-- ) result *= b ;
  22.   
  23.   return result ;
  24. }
  25.  
  26. void mat_scalev( Float s, XYZ *in, XYZ *out)
  27.   register Float f = s ;
  28.   out->x = in->x * f ;
  29.   out->y = in->y * f ;
  30.   out->z = in->z * f ;
  31. }
  32.  
  33. Float mat_dotp( XYZ *a, XYZ *b)
  34. {
  35.   return ((a->x) * (b->x) + (a->y) * (b->y) + (a->z) * (b->z)) ;
  36. }
  37.  
  38. void mat_addv( XYZ *a, XYZ *b, XYZ *out )
  39.   out->x =a->x + b->x ;
  40.   out->y =a->y + b->y ;
  41.   out->z =a->z + b->z ;
  42. }
  43.  
  44. void mat_subv( XYZ *a, XYZ *b, XYZ *out )
  45.   out->x =a->x - b->x ;
  46.   out->y =a->y - b->y ;
  47.   out->z =a->z - b->z ;
  48. }
  49.  
  50. void mat_combv( Float t, XYZ *a, XYZ *b, XYZ *out )
  51. {
  52.   out->x = t * a->x + b->x ;
  53.   out->y = t * a->y + b->y ;
  54.   out->z = t * a->z + b->z ;
  55. }
  56.  
  57. Float mat_length( XYZ *a )
  58.   return  (Float) sqrt ( sqr(a->x ) + sqr(a->y) + sqr(a->z) ) ;
  59. }
  60.  
  61. Float mat_normalize( XYZ *a )
  62. {
  63.    Float n, nn ;
  64.  
  65.    nn = sqr(a->x) + sqr(a->y) + sqr(a->z) ; 
  66.    if ( nn < ZERO ) return 0.0 ; 
  67.  
  68.    nn = (Float) sqrt(nn) ;
  69.    n = 1.0f / nn ;
  70.    a->x *= n ; 
  71.    a->y *= n ; 
  72.    a->z *= n ; 
  73.    return nn ;
  74. }   
  75. void mat_crossp( XYZ *a, XYZ *b, XYZ *out )
  76.   out->x = a->y * b->z - b->y * a->z ;
  77.   out->y = b->x * a->z - a->x * b->z ;
  78.   out->z = a->x * b->y - b->x * a->y ; 
  79. }
  80.  
  81.  
  82. void mat_rotv( XYZ *e, XYZ *p, XYZ *o )
  83. {
  84.   Float m = (Float)sqrt( sqr( p->y ) + sqr( p->z ) ) ;
  85.   Float im = 1.0f / m ;
  86.  
  87.   o->x = m * e->x + p->x * e->z ;
  88.   o->y = ( -p->x * p->y * e->x  + p->z * e->y ) * im + p->y * e->z ;
  89.   o->z = ( -p->x * p->z * e->x  - p->y * e->y ) * im + p->z * e->z ;
  90. }
  91.  
  92. void mat_randomDir( XYZ *d )
  93. {
  94.     d->x = 1 - 2 * rnd() ;
  95.     d->y = 1 - 2 * rnd() ;
  96.     d->z = 1 - 2 * rnd() ;
  97.     mat_direction( d ) ;
  98. }
  99.  
  100. void mat_printv( XYZ *a )
  101. {
  102.   fprintf(stderr,">%12g\t%12g\t%12g\n",(double)a->x , (double)a->y , (double)a->z ) ;
  103. }
  104.  
  105. void mat_printXYZW( XYZW *a )
  106. {
  107.     Float x, y, z ;
  108.     
  109.     x = (Float)(a->x / a->w) ;
  110.     y = (Float)(a->y / a->w) ;
  111.     z = (Float)(a->z / a->w) ;
  112.     
  113.     fprintf(stderr,">%8g\t%8g\t%8g\t%8g\n",(double)a->x , (double)a->y , (double)a->z, (double)a->w) ;
  114.     fprintf(stderr,"3D ->[%8g\t%8g\t%8g]\n", (double)x, (double)y, (double)z ) ;
  115. }
  116.  
  117. void mat_mult_m_XYZp( XYZ *v, Matrix a, XYZ *out )
  118. {
  119.   out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] + a[0][3] ;
  120.   out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] + a[1][3] ;
  121.   out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] + a[2][3] ;
  122. }
  123.  
  124. void mat_mult_m_XYZWp( XYZ *v, Matrix a, XYZW *out )
  125. {
  126.   out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] + a[0][3] ;
  127.   out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] + a[1][3] ;
  128.   out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] + a[2][3] ;
  129.   out->w = v->x * a[3][0] + v->y * a[3][1] + v->z * a[3][2] + a[3][3] ;
  130. }
  131.  
  132. void mat_mult_m_XYZv( XYZ *v, Matrix a, XYZ *out )
  133. {
  134.   out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] ;
  135.   out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] ;
  136.   out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] ;
  137. }
  138.  
  139. void mat_multpm( XYZ *v, Matrix a, XYZW *out )
  140. {
  141.   out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] + a[0][3] ;
  142.   out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] + a[1][3] ;
  143.   out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] + a[2][3] ;
  144.   out->w = v->x * a[3][0] + v->y * a[3][1] + v->z * a[3][2] + a[3][3] ;
  145. }
  146.  
  147. void mat_multvm(XYZ *v, Matrix a, XYZ *out )
  148.   out->x = v->x * a[0][0] + v->y * a[0][1] + v->z * a[0][2] ;
  149.   out->y = v->x * a[1][0] + v->y * a[1][1] + v->z * a[1][2] ;
  150.   out->z = v->x * a[2][0] + v->y * a[2][1] + v->z * a[2][2] ;
  151. }
  152.  
  153. void mat_mult_tm_XYZv(XYZ *v, Matrix a, XYZ *out )
  154.   out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
  155.   out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
  156.   out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
  157. }
  158. void mat_mult_tm_XYZp(XYZ *v, Matrix a, XYZ *out )
  159. {  
  160.   out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
  161.   out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
  162.   out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
  163.  
  164.   out->x -= a[0][0] * a[0][3] + a[1][0] * a[1][3] + a[2][0] * a[2][3] ;
  165.   out->y -= a[0][1] * a[0][3] + a[1][1] * a[1][3] + a[2][1] * a[2][3] ;
  166.   out->z -= a[0][2] * a[0][3] + a[1][2] * a[1][3] + a[2][2] * a[2][3] ;
  167. }
  168.  
  169. void mat_multvtm(XYZ *v, Matrix a, XYZ *out )
  170.   out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
  171.   out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
  172.   out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
  173. }
  174.  
  175. void mat_multpim(XYZ *v, Matrix a, XYZ *out )
  176. {  
  177.   out->x = v->x * a[0][0] + v->y * a[1][0] + v->z * a[2][0] ;
  178.   out->y = v->x * a[0][1] + v->y * a[1][1] + v->z * a[2][1] ;
  179.   out->z = v->x * a[0][2] + v->y * a[1][2] + v->z * a[2][2] ;
  180.  
  181.   out->x -= a[0][0] * a[0][3] + a[1][0] * a[1][3] + a[2][0] * a[2][3] ;
  182.   out->y -= a[0][1] * a[0][3] + a[1][1] * a[1][3] + a[2][1] * a[2][3] ;
  183.   out->z -= a[0][2] * a[0][3] + a[1][2] * a[1][3] + a[2][2] * a[2][3] ;
  184. }
  185.  
  186. void mat_summ( Matrix a, Matrix b, Matrix out )
  187. {
  188.   register int k;
  189.   for(k=3 ; k>=0 ; k--) 
  190.     {
  191.       out[0][k] = a[0][k] + b[0][k] ;
  192.       out[1][k] = a[1][k] + b[1][k] ;
  193.       out[2][k] = a[2][k] + b[2][k] ;
  194.       out[3][k] = a[3][k] + b[3][k] ;
  195.     }
  196. }
  197.  
  198. void mat_subm( Matrix a, Matrix b, Matrix out)
  199. {
  200.   register int k;
  201.   for(k=3 ; k>=0 ; k--) 
  202.     {
  203.       out[0][k] = a[0][k] - b[0][k] ;
  204.       out[1][k] = a[1][k] - b[1][k] ;
  205.       out[2][k] = a[2][k] - b[2][k] ;
  206.       out[3][k] = a[3][k] - b[3][k] ;
  207.     }
  208. }
  209.  
  210. void mat_multm(Matrix a, Matrix b, Matrix out )
  211. {
  212.   register int i, j ;
  213.   for(i=3 ; i>=0 ; i--)
  214.       for(j=3 ; j>=0 ; j--)
  215.         out[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j] + a[i][3] * b[3][j] ; 
  216. }
  217.  
  218. void mat_idm( Matrix out )
  219.  register int i, j ;
  220.  for( i = 0 ; i < 4 ; i++ )
  221.      for( j = 0 ; j < 4 ; j++ ) out[i][j] = ( i == j ? 1.0f : 0.0f ) ;
  222. }
  223.  
  224. void mat_transl( XYZ *v, Matrix out )
  225. {
  226.   mat_idm( out ) ;
  227.   out[0][3] = v->x ;
  228.   out[1][3] = v->y ;
  229.   out[2][3] = v->z ;
  230. }
  231.  
  232. void mat_scale( XYZ *v, Matrix out )
  233. {
  234.   mat_idm( out );
  235.   out[0][0] = v->x ;
  236.   out[1][1] = v->y ;
  237.   out[2][2] = v->z ;
  238. }
  239.  
  240. void mat_rotx(Float degrees, Matrix out )
  241.   Float c, s ;
  242.   c = (Float)cos( RAD( degrees ) ) ;
  243.   s = (Float)sin( RAD( degrees) ) ;
  244.   mat_idm( out ) ;
  245.   out[1][1] = c ;
  246.   out[2][2] = c ;
  247.   out[1][2] = -s ;
  248.   out[2][1] = s ;
  249. }
  250.  
  251. void mat_roty(Float degrees, Matrix out ) 
  252.   Float c, s ;
  253.   c = (Float)cos( RAD( degrees ) ) ;
  254.   s = (Float)sin( RAD( degrees ) ) ;
  255.   mat_idm( out ) ;
  256.   out[0][0] = c ;
  257.   out[2][2] = c ;
  258.   out[0][2] = s ;
  259.   out[2][0] = -s ;
  260. }
  261.  
  262. void mat_rotz(Float degrees, Matrix out ) 
  263.   Float c,s;
  264.   c = (Float)cos( RAD( degrees ) ) ;
  265.   s = (Float)sin( RAD( degrees ) ) ;
  266.   mat_idm( out ) ;
  267.   out[0][0] = c ;
  268.   out[1][1] = c ;
  269.   out[0][1] = -s ;
  270.   out[1][0] = s ;
  271. }
  272.  
  273. void mat_shearx( Float sy, Float sz, Matrix out )
  274. {
  275.     mat_idm( out ) ;
  276.     out[1][0] = sy ;
  277.     out[2][0] = sz ;
  278. }
  279. void mat_sheary( Float sx, Float sz, Matrix out )
  280. {
  281.     mat_idm( out ) ;
  282.     out[0][1] = sx ;
  283.     out[2][1] = sz ;
  284. }
  285.  
  286. void mat_shearz( Float sx, Float sy, Matrix out )
  287. {
  288.     mat_idm( out ) ;
  289.     out[0][2] = sx ;
  290.     out[1][2] = sy ;
  291. }
  292.  
  293.  
  294. void mat_transpose( Matrix in, Matrix out )
  295. {
  296.     int i, j ;
  297.     for( i = 0 ; i < 4 ; i++ )
  298.         for( j = 0 ; j < 4 ; j++ ) out[i][j] = in[j][i] ;
  299. }
  300.  
  301. void mat_invm( Matrix m, Matrix out )
  302. {
  303.   register int i, j ;
  304.  
  305.   mat_idm( out ) ;
  306.   for ( i = 0 ; i < 3 ; i++ )
  307.     for ( j = 0 ; j < 3; j++ )
  308.       out[i][j] = m[j][i] ;
  309.   
  310.   for ( i = 0 ; i < 3 ; i++ )
  311.     out[i][3] = -( m[0][i] * m[0][3] + m[1][i] * m[1][3] + m[2][i] * m[2][3] ) ;
  312.   
  313. }
  314.  
  315.  
  316. void mat_printm( char *s, Matrix m )
  317. {
  318.   int j ;
  319.   fprintf(stderr, "%s\n", s) ;
  320.   for( j = 0 ; j < 4 ; j++ )
  321.     fprintf(stderr, "%8.6g\t%8.6g\t%8.6g\t%8.6g\n", m[j][0], m[j][1], m[j][2], m[j][3] ) ;
  322. }
  323.  
  324.  
  325. #define mat_Accumulate    if( temp >= 0.0 ) pos += temp ; else neg += temp 
  326. #define Precision_Limit   1e-15 
  327.  
  328. Bool mat_ainvm( Matrix i , Matrix o )
  329. {
  330.   double det_1 ;
  331.   double pos, neg, temp ;
  332.  
  333.   pos = neg = 0.0 ;
  334.   temp = i[0][0] * i[1][1] * i[2][2] ;
  335.   mat_Accumulate ;
  336.   temp = i[0][1] * i[1][2] * i[2][0] ;
  337.   mat_Accumulate ;
  338.   temp = i[0][2] * i[1][0] * i[2][1] ;
  339.   mat_Accumulate ;
  340.   temp = -i[0][2] * i[1][1] * i[2][0] ;
  341.   mat_Accumulate ;
  342.   temp = -i[0][1] * i[1][0] * i[2][2] ;
  343.   mat_Accumulate ;
  344.   temp = -i[0][0] * i[1][2] * i[2][1] ;
  345.   mat_Accumulate ;
  346.   det_1 = pos + neg ;
  347.  
  348.   if( det_1 == 0.0 || fabs( det_1 / ( pos - neg )) < Precision_Limit )
  349.     {
  350.       fprintf( stderr," Singular Matrix, cannot invert.\n");
  351.       return False ;
  352.     }
  353.  
  354.   det_1 = 1.0 / det_1 ;
  355.   
  356.   o[0][0] = (Float)( ( i[1][1] * i[2][2] - i[1][2] * i[2][1] ) * det_1 ) ;
  357.   o[1][0] = (Float)(-( i[1][0] * i[2][2] - i[1][2] * i[2][0] ) * det_1 ) ;
  358.   o[2][0] = (Float)( ( i[1][0] * i[2][1] - i[1][1] * i[2][0] ) * det_1 ) ;
  359.   o[3][0] = 0.0 ;
  360.  
  361.   o[0][1] = (Float)(-( i[0][1] * i[2][2] - i[0][2] * i[2][1] ) * det_1 ) ;
  362.   o[1][1] = (Float)( ( i[0][0] * i[2][2] - i[0][2] * i[2][0] ) * det_1 ) ;
  363.   o[2][1] = (Float)(-( i[0][0] * i[2][1] - i[0][1] * i[2][0] ) * det_1 ) ;
  364.   o[3][1] = 0.0 ;
  365.  
  366.   o[0][2] = (Float)( ( i[0][1] * i[1][2] - i[0][2] * i[1][1] ) * det_1 ) ;
  367.   o[1][2] = (Float)(-( i[0][0] * i[1][2] - i[0][2] * i[1][0] ) * det_1 ) ;
  368.   o[2][2] = (Float)( ( i[0][0] * i[1][1] - i[0][1] * i[1][0] ) * det_1 ) ;  
  369.   o[3][2] = 0.0 ;
  370.  
  371.   o[0][3] = (Float)(- ( i[0][3] * o[0][0] + i[1][3] * o[0][1] + i[2][3] * o[0][2] )) ;
  372.   o[1][3] = (Float)(- ( i[0][3] * o[1][0] + i[1][3] * o[1][1] + i[2][3] * o[1][2] )) ;
  373.   o[2][3] = (Float)(- ( i[0][3] * o[2][0] + i[1][3] * o[2][1] + i[2][3] * o[2][2] )) ;
  374.   o[3][3] = 1.0 ;
  375.   
  376.   return True ;
  377. }
  378.